using System;
using System.Collections.Generic;
using System.Text;

using Liberty.Application.Security;

using Liberty.Domain.CaseManagement;
using Liberty.Domain.GrantManagement;
using Liberty.Domain.NoteManagement;

using Liberty.Persistence;
using Liberty.Persistence.GrantManagement;
using Liberty.Persistence.NoteManagement;

using Peradigm.Framework.Domain.Collections;
using Peradigm.Framework.Domain.Collections.Generic;
using Peradigm.Framework.Domain.Parties;
using Peradigm.Framework.Domain.Security;

namespace Liberty.Application.GrantManagement
{
    [Serializable]
    public class GrantController : AbstractController
    {
        #region Constants
        private const string DEFAULT_NOTES_SORT = "DateCreated";
        #endregion

        #region Event Handlers
        #endregion

        #region Methods
        public void ApplyGrantStatesOnGrant()
        {
            Grant.BuildGrantStatesByOidListFrom( this.GrantBroker.GrantStates() );
        }

        public List<GrantType> GrantTypes()
        {
            return this.GrantBroker.GrantTypes();
        }

        public GrantType GrantTypeWith( long oid )
        {
            return this.GrantBroker.GrantTypeWith( oid );
        }

        public List<PaymentType> PaymentTypes()
        {
            return this.GrantBroker.PaymentTypes();
        }

        public PaymentType PaymentTypeWith( long oid )
        {
            return this.GrantBroker.PaymentTypeWith( oid );
        }

        public List<DeliveryMethod> DeliveryMethods()
        {
            return this.GrantBroker.DeliveryMethods();
        }


        public DeliveryMethod DeliveryMethodWith( long oid )
        {
            return this.GrantBroker.DeliveryMethodWith( oid );
        }

        public List<Grant> GrantsFor( User aVolunteer )
        {
            // Get all grants, then filter by the user.
            GrantSearchCriteria criteria = new GrantSearchCriteria();
            List<Grant> grants = this.GrantBroker.GrantsMatching( criteria );

            return grants.FindAll( delegate( Grant g )
            {
                Dictionary<string, object> context = new Dictionary<string, object>();
                context.Add( ViewGrantPrivilege.KEY_USER, aVolunteer );
                context.Add( ViewGrantPrivilege.KEY_GRANT, g );
                return aVolunteer.HasPermissionTo( ViewGrantPrivilege.Actions.View, context );
            } );
        }


        public List<RelationshipType> RelationshipTypes()
        {
            return this.GrantBroker.RelationshipTypes();
        }

        public Grant SaveGrant( Grant grant )
        {
            return this.GrantBroker.Save( grant );
        }

        public RelationshipType RelationshipTypeWith( long oid )
        {
            return this.GrantBroker.RelationshipTypeWith( oid );
        }

        public Grant NewGrant()
        {
            GrantBroker broker = new GrantBroker( this.ConnectionString );

            return new Grant();
        }

        public List<Note> NotesFrom( Grant grant )
        {
            List<Note> notes = new List<Note>( grant.Notes );
            if( notes.Count == 0 )
            {
                notes = this.PrimNotesFor( grant );
            }
            notes.Sort( new Sorter<Note>( SortOrder.Descending, DEFAULT_NOTES_SORT ) );
            return notes;
        }

        public Note SaveNote( Grant grant, Note note )
        {
            NoteBroker noteBroker = new NoteBroker( this.ConnectionString );
            Note newNote = noteBroker.SaveNote( grant, note );
            grant.AddNote( note );
            return newNote;
        }
        #endregion

        #region Properties
        public GrantBroker GrantBroker
        {
            get
            {
                return this.i_GrantBroker;
            }
            set
            {
                this.i_GrantBroker = value;
            }
        }
        #endregion

        #region Private Methods
        private List<Note> PrimNotesFor( Grant grant )
        {
            grant.RemoveNotes();
            NoteBroker noteBroker = new NoteBroker( this.ConnectionString );
            List<Note> notes = noteBroker.NotesFor( grant );
            return notes;
        }
        #endregion

        #region Private Properties
        #endregion

        #region Construction and Finalization
        public GrantController()
            : base()
        {
            string cxnString = base.ConnectionString;
            this.i_GrantBroker = new GrantBroker( cxnString );
        }
        #endregion

        #region Data Elements
        private GrantBroker i_GrantBroker = null;
        #endregion
    }
}
